#include "string.h"
#include "global.h"
#include "debug.h"

void memset(void* dst_, uint8_t value, uint32_t size)
{
    ASSERT(dst_ != NULL);
    uint8_t * dst = (uint8_t *)dst_;
    while(size-- >0){
        *dst++ = value;
        dst++;
    }
}


void memcpy(void* dst_, const void* src_, uint32_t size)
{
    ASSERT(dst_ != NULL);
    ASSERT(src_ != NULL);
    uint8_t * dst = (uint8_t *)dst_;
    uint8_t * src = (uint8_t *)src_;

    while(size -- >0){
        *dst = *src;
        src++;
        dst++;
    }
}

int memcmp(const void* a_, const void* b_, uint32_t size)
{
    ASSERT(a_ != NULL);
    ASSERT(b_ != NULL);
    uint8_t * a = (uint8_t *)a_;
    uint8_t * b = (uint8_t *)b_;

    while(size-- >0){
        if(*a != *b){
            return a > b ? 1 : -1;
        }
        a++;
        b++;
    }
    return 0;
}

char* strcpy(char* dst_, const char* src_)
{
    ASSERT(dst_ != NULL);
    ASSERT(src_ != NULL);
    uint8_t * dst = (uint8_t *)dst_;
    uint8_t * src = (uint8_t *)src_;
    char* r = dst_;
    while((*dst++ = *src++ ));

    return r;

}

uint32_t strlen(const char* str)
{
    ASSERT(str != NULL);
    const char* p = str;
    
    while(*p++);
    return (p - str - 1);
}



int8_t strcmp (const char* a, const char* b) {
    ASSERT(a != NULL && b != NULL);
    while (*a != 0 && *a == *b) {
        a++;
        b++;
    }
/* 如果*a小于*b就返回-1,否则就属于*a大于等于*b的情况。在后面的布尔表达式"*a > *b"中,
 * 若*a大于*b,表达式就等于1,否则就表达式不成立,也就是布尔值为0,恰恰表示*a等于*b */
    return *a < *b ? -1 : *a > *b;
}


char* strchr(const char* str, const uint8_t ch) {
    ASSERT(str != NULL);
    while (*str != 0) {
        if (*str == ch) {
	        return (char*)str;	    // 需要强制转化成和返回值类型一样,否则编译器会报const属性丢失,下同.
        }
        str++;
    }
    return NULL;
}


char* strrchr(const char* str, const uint8_t ch) {
    ASSERT(str != NULL);
    const char* last_char = NULL;
    /* 从头到尾遍历一次,若存在ch字符,last_char总是该字符最后一次出现在串中的地址(不是下标,是地址)*/
    while (*str != 0) {
        if (*str == ch) {
	        last_char = str;
        }
        str++;
    }
    return (char*)last_char;
}


char* strcat(char* dst_, const char* src_) {
    ASSERT(dst_ != NULL && src_ != NULL);
    char* str = dst_;
    while (*str++);
    --str;                       // 别看错了，--str是独立的一句，并不是while的循环体。这一句是为了让str指向dst_的最后一个非0字符
    while((*str++ = *src_++));	//1、*str=*src  2、判断*str     3、str++与src++，这一步不依赖2
    return dst_;
}


uint32_t strchrs(const char* str, uint8_t ch) {
    ASSERT(str != NULL);
    uint32_t ch_cnt = 0;
    const char* p = str;
    while(*p != 0) {
        if (*p == ch) {
            ch_cnt++;
        }
        p++;
    }
    return ch_cnt;
}
